<?
/**
 * Forms Functions
 *
 * various functions that assist in rendering forms and retrieiving data.
 *
 * LICENSE: GPL Version 2
 *
 * @copyright	2006 SANS Institute
 * @license		http://www.gnu.org/copyleft/gpl.html
 * @version 	$id$
 * @since 		File available since Release 1
 */


/*
* couple of arrays that are used to assemble and validate dates
* (maybe they belong into 'lists.php' ?)
*/

$aDAYS=array(1=>1,2=>2,3=>3,4=>4,5=>5,6=>6,7=>7,8=>8,9=>9,10=>10,11=>11,12=>12,
13=>13,14=>14,15=>15,16=>16,17=>17,18=>18,19=>19,20=>20,21=>21,
22=>22,23=>23,24=>24,25=>25,26=>26,27=>27,28=>28,29=>29,30=>30,
31=>31);
$aMONTHS=array("1"=>"Jan","2"=>"Feb","3"=>"Mar","4"=>"Apr","5"=>"May",
"6"=>"Jun","7"=>"Jul","8"=>"Aug","9"=>"Sep","10"=>"Oct",
"11"=>"Nov","12"=>"Dec");
$aYEARS=array(2000=>2000,2001=>2001,2002=>2002,2003=>2003,2004=>2004,
2005=>2005,2006=>2006,2007=>2007,2008=>2008,2009=>2009);
$aPROTOCOLS=array('tcp'=>'tcp','udp'=>'udp');
$aSIZES=array('S','M','L','XL','XXL','XXXL');
$aRegions=array("AF"=>"Africa",
                "AS"=>"Asia",
                "AU"=>"Australia/New Zealand",
                "EU"=>"Europe",
                "NA"=>"North America",
                "SA"=>"South America");
$aCountries=array(
             "AF"=>"AFGHANISTAN",
             "AL"=>"ALBANIA",
             "DZ"=>"ALGERIA",
             "AS"=>"AMERICAN SAMOA",
             "AD"=>"ANDORRA",
             "AO"=>"ANGOLA",
             "AI"=>"ANGUILLA",
             "AQ"=>"ANTARCTICA",
             "AG"=>"ANTIGUA AND BARBUDA",
             "AR"=>"ARGENTINA",
             "AM"=>"ARMENIA",
             "AW"=>"ARUBA",
             "AU"=>"AUSTRALIA",
             "AT"=>"AUSTRIA",
             "AZ"=>"AZERBAIJAN",
             "BS"=>"BAHAMAS",
             "BH"=>"BAHRAIN",
             "BD"=>"BANGLADESH",
             "BB"=>"BARBADOS",
             "BY"=>"BELARUS",
             "BE"=>"BELGIUM",
             "BZ"=>"BELIZE",
             "BJ"=>"BENIN",
             "BM"=>"BERMUDA",
             "BT"=>"BHUTAN",
             "BO"=>"BOLIVIA",
             "BA"=>"BOSNIA AND HERZEGOWINA",
             "BW"=>"BOTSWANA",
             "BV"=>"BOUVET ISLAND",
             "BR"=>"BRAZIL",
             "IO"=>"BRITISH INDIAN OCEAN TERRITORY",
             "BN"=>"BRUNEI DARUSSALAM",
             "BG"=>"BULGARIA",
             "BF"=>"BURKINA FASO",
             "BI"=>"BURUNDI",
             "KH"=>"CAMBODIA",
             "CM"=>"CAMEROON",
             "CA"=>"CANADA",
             "CV"=>"CAPE VERDE",
             "KY"=>"CAYMAN ISLANDS",
             "CF"=>"CENTRAL AFRICAN REPUBLIC",
             "TD"=>"CHAD",
             "CL"=>"CHILE",
             "CN"=>"CHINA",
             "CX"=>"CHRISTMAS ISLAND",
             "CC"=>"COCOS (KEELING) ISLANDS",
             "CO"=>"COLOMBIA",
             "KM"=>"COMOROS",
             "CG"=>"CONGO",
             "CK"=>"COOK ISLANDS",
             "CR"=>"COSTA RICA",
             "CI"=>"COTE D'IVOIRE",
             "HR"=>"CROATIA (local name: Hrvatska)",
             "CU"=>"CUBA",
             "CY"=>"CYPRUS",
             "CZ"=>"CZECH REPUBLIC",
             "DK"=>"DENMARK",
             "DJ"=>"DJIBOUTI",
             "DM"=>"DOMINICA",
             "DO"=>"DOMINICAN REPUBLIC",
             "TP"=>"EAST TIMOR",
             "EC"=>"ECUADOR",
             "EG"=>"EGYPT",
             "SV"=>"EL SALVADOR",
             "GQ"=>"EQUATORIAL GUINEA",
             "ER"=>"ERITREA",
             "EE"=>"ESTONIA",
             "ET"=>"ETHIOPIA",
             "EU"=>"EUROPE",
             "FK"=>"FALKLAND ISLANDS (MALVINAS)",
             "FO"=>"FAROE ISLANDS",
             "FJ"=>"FIJI",
             "FI"=>"FINLAND",
             "FR"=>"FRANCE",
             "FX"=>"FRANCE, METROPOLITAN",
             "GF"=>"FRENCH GUIANA",
             "PF"=>"FRENCH POLYNESIA",
             "TF"=>"FRENCH SOUTHERN TERRITORIES",
             "GA"=>"GABON",
             "GM"=>"GAMBIA",
             "GE"=>"GEORGIA",
             "DE"=>"GERMANY",
             "GH"=>"GHANA",
             "GI"=>"GIBRALTAR",
             "GR"=>"GREECE",
             "GL"=>"GREENLAND",
             "GD"=>"GRENADA",
             "GP"=>"GUADELOUPE",
             "GU"=>"GUAM",
             "GT"=>"GUATEMALA",
             "GN"=>"GUINEA",
             "GW"=>"GUINEA-BISSAU",
             "GY"=>"GUYANA",
             "HT"=>"HAITI",
             "HM"=>"HEARD AND MC DONALD ISLANDS",
             "HN"=>"HONDURAS",
             "HK"=>"HONG KONG",
             "HU"=>"HUNGARY",
             "IS"=>"ICELAND",
             "IN"=>"INDIA",
             "ID"=>"INDONESIA",
             "IR"=>"IRAN (ISLAMIC REPUBLIC OF)",
             "IQ"=>"IRAQ",
             "IE"=>"IRELAND",
             "IL"=>"ISRAEL",
             "IT"=>"ITALY",
             "JM"=>"JAMAICA",
             "JP"=>"JAPAN",
             "JO"=>"JORDAN",
             "KZ"=>"KAZAKHSTAN",
             "KE"=>"KENYA",
             "KI"=>"KIRIBATI",
             "KP"=>"KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF",
             "KR"=>"KOREA, REPUBLIC OF",
             "KW"=>"KUWAIT",
             "KG"=>"KYRGYZSTAN",
             "LA"=>"LAO PEOPLE'S DEMOCRATIC REPUBLIC",
             "LV"=>"LATVIA",
             "LB"=>"LEBANON",
             "LS"=>"LESOTHO",
             "LR"=>"LIBERIA",
             "LY"=>"LIBYAN ARAB JAMAHIRIYA",
             "LI"=>"LIECHTENSTEIN",
             "LT"=>"LITHUANIA",
             "LU"=>"LUXEMBOURG",
             "MO"=>"MACAU",
             "MK"=>"MACEDONIA",
             "MG"=>"MADAGASCAR",
             "MW"=>"MALAWI",
             "MY"=>"MALAYSIA",
             "MV"=>"MALDIVES",
             "ML"=>"MALI",
             "MT"=>"MALTA",
             "MH"=>"MARSHALL ISLANDS",
             "MQ"=>"MARTINIQUE",
             "MR"=>"MAURITANIA",
             "MU"=>"MAURITIUS",
             "YT"=>"MAYOTTE",
             "MX"=>"MEXICO",
             "FM"=>"MICRONESIA,FEDERATED STATES OF",
             "MD"=>"MOLDOVA",
             "MC"=>"MONACO",
             "MN"=>"MONGOLIA",
             "MS"=>"MONTSERRAT",
             "MA"=>"MOROCCO",
             "MZ"=>"MOZAMBIQUE",
             "MM"=>"MYANMAR",
             "NA"=>"NAMIBIA",
             "NR"=>"NAURU",
             "NP"=>"NEPAL",
             "AN"=>"NETHERLANDS ANTILLES",
             "NL"=>"NETHERLANDS",
             "NC"=>"NEW CALEDONIA",
             "NZ"=>"NEW ZEALAND",
             "NI"=>"NICARAGUA",
             "NE"=>"NIGER",
             "NG"=>"NIGERIA",
             "NU"=>"NIUE",
             "NF"=>"NORFOLK ISLAND",
             "MP"=>"NORTHERN MARIANA ISLANDS",
             "NO"=>"NORWAY",
             "OM"=>"OMAN",
             "PK"=>"PAKISTAN",
             "PW"=>"PALAU",
             "PS"=>"PALESTINIAN TERRITORY",
             "PA"=>"PANAMA",
             "PG"=>"PAPUA NEW GUINEA",
             "PY"=>"PARAGUAY",
             "PE"=>"PERU",
             "PH"=>"PHILIPPINES",
             "PN"=>"PITCAIRN",
             "PL"=>"POLAND",
             "PT"=>"PORTUGAL",
             "PR"=>"PUERTO RICO",
             "QA"=>"QATAR",
             "XX"=>"RESERVED",
             "RE"=>"REUNION",
             "RO"=>"ROMANIA",
             "RU"=>"RUSSIAN FEDERATION",
             "RW"=>"RWANDA",
             "KN"=>"SAINT KITTS AND NEVIS",
             "LC"=>"SAINT LUCIA",
             "VC"=>"SAINT VINCENT AND THE GRENADINES",
             "WS"=>"SAMOA",
             "SM"=>"SAN MARINO",
             "ST"=>"SAO TOME AND PRINCIPE",
             "SA"=>"SAUDI ARABIA",
             "SN"=>"SENEGAL",
             "CS"=>"SERBIA AND MONTENEGRO",
             "SC"=>"SEYCHELLES",
             "SL"=>"SIERRA LEONE",
             "SG"=>"SINGAPORE",
             "SK"=>"SLOVAKIA (Slovak Republic)",
             "SI"=>"SLOVENIA",
             "SB"=>"SOLOMON ISLANDS",
             "SO"=>"SOMALIA",
             "ZA"=>"SOUTH AFRICA",
             "ES"=>"SPAIN",
             "LK"=>"SRI LANKA",
             "SH"=>"ST. HELENA",
             "PM"=>"ST. PIERRE AND MIQUELON",
             "SD"=>"SUDAN",
             "SR"=>"SURINAME",
             "SJ"=>"SVALBARD AND JAN MAYEN ISLANDS",
             "SZ"=>"SWAZILAND",
             "SE"=>"SWEDEN",
             "CH"=>"SWITZERLAND",
             "SY"=>"SYRIAN ARAB REPUBLIC",
             "TW"=>"TAIWAN",
             "TJ"=>"TAJIKISTAN",
             "TZ"=>"TANZANIA, UNITED REPUBLIC OF",
             "TH"=>"THAILAND",
             "CD"=>"THE DEMOCRATIC REPUBLIC OF THE CONGO",
             "TL"=>"TIMOR-LESTE",
             "TG"=>"TOGO",
             "TK"=>"TOKELAU",
             "TO"=>"TONGA",
             "TT"=>"TRINIDAD AND TOBAGO",
             "TN"=>"TUNISIA",
             "TR"=>"TURKEY",
             "TM"=>"TURKMENISTAN",
             "TC"=>"TURKS AND CAICOS ISLANDS",
             "TV"=>"TUVALU",
             "UG"=>"UGANDA",
             "UA"=>"UKRAINE",
             "AE"=>"UNITED ARAB EMIRATES",
             "GB"=>"UNITED KINGDOM",
             "UM"=>"UNITED STATES MINOR OUTLYING ISLANDS",
             "US"=>"UNITED STATES",
             "UY"=>"URUGUAY",
             "UZ"=>"UZBEKISTAN",
             "VU"=>"VANUATU",
             "VA"=>"VATICAN CITY STATE (HOLY SEE)",
             "VE"=>"VENEZUELA",
             "VN"=>"VIET NAM",
             "VG"=>"VIRGIN ISLANDS (BRITISH)",
             "VI"=>"VIRGIN ISLANDS (U.S.)",
             "WF"=>"WALLIS AND FUTUNA ISLANDS",
             "EH"=>"WESTERN SAHARA",
             "YE"=>"YEMEN",
             "YU"=>"YUGOSLAVIA",
             "ZR"=>"ZAIRE",
             "ZM"=>"ZAMBIA",
             "ZW"=>"ZIMBABWE"

);
function is_handler($bLoggedIn,$oUser) {

  if ( $bLoggedIn ) {
    if ( $oUser->ishandler() ) {
      return true;
    } else {
      redirect("/login.html?nohandler",array("level"=>"INFO","message"=>"handler test failed - no handler"));
      exit();
    }
  }
  redirect("/login.html?nologin",array("level"=>"INFO","message"=>"handler test failed - not logged in")); 
  return false;
}

function formsafe($sValue) {
  $sValue=str_replace('"','',$sValue);  
  return $sValue;
}

/**
 * create a nicely formated form field. This is a wrapper function around
 * private functions
 * 
 * @param string $sType type of form. Valid values: text, textarea, checkbox, radio, select
 * @param string $sName name of the form field
 * @param string $sValue prefill value
 * @param array  $aParam additional type specific parameters.
 * @return string the HTML snippet for the form filed.
 */
function form_field($sType,$sName,$sValue='',$bRequired=FALSE,$aParam='') {
  if ( ! is_array($aParam) ) {
    $aParam=array();
  }
  if (key_exists('size',$aParam)) {
    $nSize=$aParam['size'];
  } 
  if (key_exists('rows',$aParam)) {
    $nRows=$aParam['rows'];
  } 
  if (key_exists('cols',$aParam)) {
    $nCols=$aParam['cols'];
  } 
  if (key_exists('maxsize',$aParam)) {
    $nMaxSize=$aParam['maxsize'];
  }
  if (key_exists('additional',$aParam)) {
    $sAdd=$aParam['additional'];
  } 
  switch ($sType) {
  case "text":
    return textform($sName,$sValue,$nSize,$nMaxSize,$bRequired,$sAdd); 
  case "phone":
    return textform($sName,$sValue,15,25,$bRequired,$sAdd); 
  case "number":
    return textform($sName,$sValue,15,25,$bRequired,$sAdd); 
  case "email":
    return textform($sName,$sValue,30,255,$bRequired,$sAdd); 
  case "static":
    return $sValue;
  case "textarea":
    return textareaform($sName,$sValue,$nRows,$nCols,$bRequired,$sAdd);
  case "yn":
    return checkbox($sName,'Y',$sValue);
  }
    
  return('');
}
function form_header($sAction='') {
  if ( $sAction=='' ) {
    $sAction=$_SERVER['REQUEST_URI'];
  }
  return "<form method=\"POST\" action=\"$sAction\">".csrftoken();

}
function csrftoken() {
  global $sCSRFToken;
  return "<input type=\"hidden\" name=\"token\" value=\"$sCSRFToken\" />";
}

function read_form($aForm,$aData,$sMethod='_REQUEST',$bDebug=FALSE) {

  global ${$sMethod};
  foreach($aForm as $sKey=>$aLine ) {
    if ( $bDebug ) {
      dprint("read_form key $sKey");
      dprint($aLine);
      dprint("before {$aData[$sKey]}");
    }
    switch ( $aLine[1] ) {
    case "text":
      $aData[$sKey]=request_cleantext($sKey,$aData[$sKey],$sMethod,$sDebug);
      break;
    case "email":
      $aData[$sKey]=request_email($sKey,$aData[$sKey],$sMethod,$bDebug);
      break;
    case "textarea":
      $aData[$sKey]=request_cleantext($sKey,$aData[$sKey],$sMethod,$bDebug);
      break;
    case "number":
      $aData[$sKey]=request_int_range($sKey,0,PHP_INT_MAX,$aData[$sKey],$sMethod,$bDebug);
      break;
    case "phone":
      $aData[$sKey]=request_phone($sKey,$aData[$sKey],$sMethod,$bDebug);
      break;
    case "static":
      break;
    case "yn":
      $aData[$sKey]=request_yn($sKey,'N',$sMethod,$bDebug);
      break;
    default:
      dprint("no validation for ".$aLine[1]);
    }
    if ( $bDebug ) {
      dprint("after ".$aData[$sKey]);
    }

  }
  return($aData);
}
/**
 * pull a text out of $_REQUEST. Note that this function does not do any validation!
 *
 * @param string $sName name of the $_REQUEST field.
 * @param string $sDefault default value in case the field is not set.
 * @return string value found in $_REQUEST (or $sDefault if not found).
 */
function request_text($sName, $sDefault='',$sMethod='_REQUEST',$bDebug=FALSE) {
  global ${$sMethod};
  if (array_key_exists($sName,${$sMethod})) {
    return ${$sMethod}[$sName];
  }
  if ( $bDebug) {
    dprint("key $sName does not exist");
  }
  return $sDefault;
}
function post_text($sName, $sDefault='',$bDebug=FALSE) {
  return request_text($sName,$sDefault,$type='_POST',$bDebug);
}

function request_hex($sName,$sDefault='',$sMethod='_REQUEST',$bDebug=FALSE) {
  global ${$sMethod};
  if (key_exists($sName,${$sMethod})) {
    return is_hex(${$sMethod}[$sName],$sDefault);
  }
  return $sDefault;
}
function post_hex($sName,$sDefault='',$bDebug=FALSE) {
  return request_hex($sName,$sDefault,'_POST',$bDebug);
}


function is_hex($sValue,$sDefault='',$bDebug=FALSE ) {
  if ( eregi('^[0-9a-h]+$',$sValue ) ) {
    return $sValue;
  }
  return $sDefault;
}

function is_phone($sValue,$sDefault='',$bDebug=FALSE) {
  if ( eregi('^\+?[0-9()\-\ ]+$',$sValue)) {
    if ($bDebug) {
      dprint("validated phone number".$sValue);
    }
    
    return $sValue;
  }
  if ($bDebug) {
    dprint("NOT valid phone number".$sValue);
  }
  return $sDefault;
}

function request_phone($sName,$sDefault='',$sMethod='_REQUEST',$bDebug=FALSE) {
  global ${$sMethod};
  if (key_exists($sName,${$sMethod}) ) {
    if ($bDebug) {
      dprint("found value".${$sMethod}[$sName]);
    }
    return is_phone(${$sMethod}[$sName],$sDefault,$bDebug);
  }
    if ($bDebug) {
      dprint("returning default");
    }

  return $sDefault;
}

function request_port($sName,$sDefault='',$sMethod='_REQUEST',$bDebug=FALSE ) {
  global ${$sMethod};
  if (array_key_exists($sName,${$sMethod}) ) {
    $sPort=${$sMethod}[$sName];
    if ( ereg('^[0-9]+$',$sPort) ) {
      if ( $sPort>-1 && $sPort<65536 ) {
        return $sPort;
      }   
    } else {
      $nPort=getservbyname($sPort,'tcp');
      if ( $nPort ) {
        return $nPort;
      }
      $nPort=getservbyname($sPort,'udp');
      if ( $nPort ) {
        return $nPort;
      }
    }
  } 
  return $sDefault; 
}
/**
 * redirect a user to a different URL cleanly.
 *
 * @param string $sURL
 */
function redirect($sURL,$aLog='') {
  applog($aLog['level'],$aLog['message']);
  session_write_close();
  header("Location: $sURL");
  exit();
}

/**
 * 'exit' from a page cleanly with saving session first.
 *
 */

function myexit() {
;    session_write_close();
    require("footer.php");
    exit();
}

/**
 * retrieve text from super global $_REQUEST and clean it up.
 *
 * @param unknown_type $sName
 * @param unknown_type $sDefault
 * @return unknown
 */
function request_cleantext($sName,$sDefault='',$sMethod='_REQUEST',$bDebug=FALSE) {
  global ${$sMethod};
    return(htmlentities(stripslashes(request_text($sName,$sDefault,$sMethod,$bDebug))));
}

function post_cleantext($sName,$sDefault='') {
    return(htmlentities(stripslashes(post_text($sName,$sDefault,FALSE))));
}
/**
 * retrieve a name from $_REQUEST super global and validate it.
 *
 * @param string $sName
 * @param string $sDefault
 * @return string
 */
function request_name($sName, $sDefault,$sMethod='_REQUEST',$bDebug=FALSE) {
  global ${$sMethod};
  if (key_exists($sName,${$sMethod})) {
    $sVal=ereg_replace('^[^a-z0-9, \'\.\-]+$','',${$sMethod}[$sName]);
    return htmlentities($sVal);
  }
  return $sDefault;
}
/**
 * pull data from $_SESSION and make sure the value exists first.
 * Note! No validation done here as this comes from server side $_SESSION
 *
 * @param string $sName name of the $_SESSION element
 * @param string $sDefault default value to use if element is not set.
 * @return string
 */
function getSession($sName,$sDefault='') {
  if ( is_array($_SESSION) ) {
    if ( key_exists($sName,$_SESSION) ) {
        return $_SESSION[$sName];
    }
  }
    return $sDefault;
}
/**
 * pull an e-mail address out of the $_REQUEST and validate it.
 *
 * @param string $sName name of the $_REQUEST element.
 * @param string $sDefault default value to use if the element is not set of if the string
 * is not a valid e-mail address.
 * @return string
 */
function request_email($sName,$sDefault='',$sMethod='_REQUEST',$bDebug=FALSE) {
  global ${$sMethod};
  if (key_exists($sName,${$sMethod})) {
    return is_email(${$sMethod}[$sName],$sDefault);
  }
  return $sDefault;
}
function post_email($sName,$sDefault='') {
  return request_email($sName,$sDefault,'_POST');
}
/**
 * validate a string to check if it is an e-mail address.
 *
 * @param string $sValue string to check
 * @param string $sDefault if the string turns out to be invalid, return this default.
 * @return string
 */
function is_email($sValue,$sDefault=FALSE) {
    if ( ereg("^([a-zA-Z0-9=_\-\.\+-\'\\&]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|([a-zA-Z0-9\.\-]+))\.([a-zA-Z]{2,4}|[0-9]{1,4})(\]?)$",$sValue) ) {
        if ( !ereg("@.*@", $sValue)) {
            return $sValue;
        }
    }
    return $sDefault;
}
/**
 * Pull a value out of $_REQUEST and validate that it is an integer within a certain range.
 *
 * @param string $sName name of $_REQUEST field
 * @param integer $nMin smallest value accepted.
 * @param integer $nMax largest value accepted.
 * @param integer $nDefault default value to use the $_REQUEST field doesn't exist or is not valid.
 * @return integer
 */
function request_int_range($sName,$nMin=0,$nMax=2147483647,$nDefault=0,$sMethod='_REQUEST') {
  global ${$sMethod};
  if (key_exists($sName,${$sMethod})) {
    $nValue=${$sMethod}[$sName];
    if ( ctype_digit($nValue) && $nValue>=$nMin && $nValue<=$nMax) {
      return $nValue;
    }
  }
  return $nDefault;
}
function get_int_range($sName,$nMin=0,$nMax=2147483647,$nDefault=0) {
    if (key_exists($sName,$_GET)) {
        $nValue=$_GET[$sName];
        if ( ctype_digit($nValue) && $nValue>=$nMin && $nValue<=$nMax) {
            return $nValue;
        }
    }
    return $nDefault;
}
function post_int_range($sName,$nMin=0,$nMax=2147483647,$nDefault=0) {
    if (key_exists($sName,$_POST)) {
        $nValue=$_POST[$sName];
        if ( ctype_digit($nValue) && $nValue>=$nMin && $nValue<=$nMax) {
            return $nValue;
        }
    }
    return $nDefault;
}
/**
 * Pull a value out of $_REQUEST and check if it is an IP address
 *
 * @param string $sName key of $_REQUEST
 * @param string $sDefault default value if the key doesn't exist or if the value isn't an IP address.
 * @return string
 */
function request_ip($sName,$sDefault='',$sMethod='_REQUEST',$bDebug=FALSE) {
  global ${$sMethod};
  if ( key_exists($sName,${$sMethod})) {
    return is_ip(${$sMethod}[$sName],$sDefault,$bDebug);
  }
    return $sDefault;
}

function request_ip6($sName,$sDefault='',$sMethod='_REQUEST',$bDebug=FALSE) {
  global ${$sMethod};
    if ( key_exists($sName,${$sMethod})) {
        return is_ip6(${$sMethod}[$sName],$sDefault);
    }
    return $sDefault;
}


function is_ip($sValue,$sDefault=FALSE) {
  if (is_ip4($sValue) ) {
    return $sValue;
  }
  if (is_ip6($sValue) ) {
    return $sValue;
  }
  return $sDefault;
}
function is_ip4($sValue,$sDefault=FALSE) {

    if ( ereg("[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}",$sValue) ) {
        $sValue=unpadip($sValue);
        $x=ip2long($sValue);
        $x=long2ip($x);
        if ( $x==$sValue ) {
            return $x;
        }
    }
    return $sDefault;
}
function is_ip6($sValue,$sDefault=FALSE) {

    if ( eregi("[0-9A-F:]+",$sValue) ) {
      return $sValue;
    }
    return $sDefault;
}
function check_request($sName,$sValue,$sMethod='_REQUEST',$bDebug=FALSE) {
  global ${$sMethod};
  if ( $bDebug  ) {
    dprint(${$sMethod});
  }
  if ( key_exists($sName,${$sMethod}) && ${$sMethod}[$sName]==$sValue) {
    if ( $bDebug ) {
      dprint("$sName $sValue match");
    }
    return true;
  }
  if ( $bDebug ) {
    dprint("$sName $sValue NO match ".${$sMethod}[$sName] ) ;
  }
  return false;
}
function request_date($sName,$dDefault='',$sMethod='_REQUEST',$bDebug=FALSE) {
  global ${$sMethod};
    if ( $dDefault=='today') {
        $dDefault=date('Y-m-d');
    }
    if (is_array(${$sMethod}) && key_exists($sName,${$sMethod})) {
        return is_date(${$sMethod}[$sName],$dDefault);
    }
    return $dDefault;
}
function request_bool($sName,$dDefault=false,$sMethod='_REQUEST',$bDebug=FALSE) {
  global ${$sMethod};
    if ( key_exists($sName,${$sMethod})) {
        $nValue=is_yn_bool(${$sMethod}[$sName],$dDefault);
        return $nValue;
    }
}
function request_yn($sName,$dDefault='N',$sMethod='_REQUEST',$bDebug=FALSE) {
    global ${$sMethod};
    if ( key_exists($sName,${$sMethod})) {
        $nValue=is_yn(${$sMethod}[$sName],$dDefault);
        return $nValue;
    }
    return $dDefault;
}

function table_dateform($sLabel,$sName,$dValue='today') {
    return "<tr valign=\"top\"><td align=\"right\">
$sLabel</td><td>".dateform($sName,$dValue)."</td></tr>";
}
/**
 * return three drop down select dialogs to enter a date.
 *
 * @param string $sName name of the field. _day, _month, _year is appended.
 * @param date $dValue prefill value.
 * @return string
 */
function dateform($sName,$dValue='today') {
    global $aMONTHS, $aDAYS, $aYEARS;
    if ( $dValue=='today' ) {
        $dValue=date('Y-m-d');
    }
    list($nYear,$nMonth,$nDay)=split('-',$dValue);

    $sForm=select($sName.'_month',$aMONTHS,$nMonth);
    $sForm.=select($sName.'_day',$aDAYS,$nDay);
    $sForm.=select($sName.'_year',$aYEARS,$nYear);
    return($sForm);
}
function table_textareaform($sLabel,$sName,$sValue='',$nRows=50,$nCols=10,$bRequired=false,$sAdd='') {
  return "<tr valign=\"top\"><td align=\"right\">$sLabel</td>
<td>".textareaform($sName,$sValue='',$nRows,$nCols,$bRequired,$sAdd)."</td></tr>";
}
function table_textform($sLabel,$sName,$sValue='',$nSize=10,$nMaxSize=255,$bRequired=false,$sAdd='') {
    return "<tr valign=\"top\"><td align=\"right\">$sLabel</td>
<td>".textform($sName,$sValue,$nSize,$nMaxSize,$bRequired,$sAdd)."</td></tr>";

}

function table_pwform($sLabel,$sName,$sValue='',$nSize=10,$nMaxSize=255,$bRequired=false) {
    return "<tr valign=\"top\"><td align=\"right\">$sLabel</td>
<td>".passwordform($sName,$sValue,$nSize,$nMaxSize,$bRequired)."</td></tr>";
}
function textform($sName,$sValue='',$nSize=10,$nMaxSize=255,$bRequired=false,$sAdd='') {

    if ( $bRequired ) {
        $sClass='formrequired';
    } else {
        $sClass='formfield';
    }
    $sValue=formsafe($sValue);
    $sForm="<input class=\"{$sClass}\" type=\"text\" name=\"$sName\" value=\"$sValue\" size=\"$nSize\" maxsize=\"$nMaxSize\" $sAdd>";
    return($sForm);
}

function textareaform($sName,$sValue='',$nRows,$nCols,$bRequired,$sAdd) {
  if ( $bRequired ) {
    $sClass='formrequired';
  } else {
    $sClass='formfield';
  }
  
  $sForm="<textarea class=\"{$sClass}\" name=\"$sName\" rows=\"$nRows\" cols=\"$nCols\" $sAdd>$sValue</textarea>";
  return($sForm);

}
function passwordform($sName,$sValue='',$nSize=10,$nMaxSize=255,$bRequired=false) {
    if ( $bRequired ) {
        $sClass='formrequired';
    } else {
        $sClass='formfield';
    }
    $sValue=formsafe($sValue);
  
    $sForm="<input class=\"{$sClass}\" type=\"password\" name=\"$sName\" value=\"$sValue\" size=\"$nSize\" maxsize=\"$nMaxSize\">";
    return($sForm);
}
function checkbox($sName,$sValue,$sSelected='') {
    $sForm='';
    if ( $sValue==$sSelected ) {
        $sForm=' CHECKED ';
    }
    $sValue=formsafe($sValue);
    return "<input class=\"formfield\" type=\"checkbox\" name=\"$sName\" value=\"$sValue\"
	 $sForm >";
}
function table_checkbox($sLabel,$sName,$sValue,$sSelected='') {
    return "<tr valign=\"top\"><td align=\"right\">$sLabel</td><td>".checkbox($sName,$sValue,$sSelected)."</td></tr>";
}
function table_radio($sLabel,$sName,$aValues,$sSelected='') {
    return "<tr valign=\"top\"><td align=\"right\">$sLabel</td><td>".radio($sName,$aValues,$sSelected)."</td></tr>";
}
function radio($sName,$aValues,$sSelected='') {
    $sForm='';
    foreach ( $aValues as $sKey=>$sValue) {
        $sS='';
        if ( $sSelected==$sKey ) {
            $sS='CHECKED';
        }
        $sForm.="$sValue <input class=\"formfield\" type=\"radio\" name=\"$sName\"
                        	value=\"$sKey\" $sS>";
    }
    return $sForm;
}
function table_select($sLabel,$sName,$aValues,$sSelected='',$sAdd='') {
    return "<tr valign=\"top\"><td
		align=\"right\">$sLabel</td><td>".select($sName,$aValues,$sSelected,$sAdd)."</td></tr>";

}

/**
 * Render a 'select' form item from an array.
 *
 * @param string $sName
 * @param array $aValues
 * @param string $sSelected
 * @return string
 */
function select($sName,$aValues,$sSelected='',$sAdd=''){
    $sForm="<select class=\"formfield\" name=\"$sName\" $sAdd>";
    foreach( $aValues as $sKey=>$sValue ) {
        $sS='';
        if ( $sKey==$sSelected) $sS='SELECTED';
        $sForm.="<option value=\"$sKey\" $sS>$sValue</option>";
    }
    $sForm.="</select>";
    return($sForm);
}

/**
 * Function returns 'true' if value is 'y' and 'false' if value is 'n'. If value is neither,
 * then the default is returned.
 *
 * @param string $sValue value to be tested
 * @param bool $bDefault default result.
 * @return bool
 */

function is_yn_bool($sValue,$bDefault=false) {
    $sValue=strtolower($sValue);
    if ( $sValue=='y') return (true);
    if ( $sValue=='n') return (false);
    return $bDefault;
}

/**
 * Check if a value is 'Y' or 'N'. Check is done not case sensitive and the
 * upper case value is returned.
 *
 * @param string $sValue
 * @param string $bDefault
 * @return string
 */

function is_yn($sValue,$bDefault='n') {
    $sValue=strtoupper($sValue);
    if ( $sValue=='Y') return ('Y');
    if ( $sValue=='N') return ('N');
    return $bDefault;
}

/**
 * This function will assemble a date from values submitted via 3 dropdown
 * selections for day/month/year. See 'dateform' for a function to render
 * compliant drop-downs.
 *
 * @param string $sName
 * @param date $dMin
 * @param date $dMax
 * @param string $dDefault
 * @return string
 */

function request_date_form($sName,$dMin,$dMax,$dDefault,$sMethod='_REQUEST',$bDebug=FALSE) {
  global ${$sMethod};
  list($nDefaultYear,$nDefaultMonth,$nDefaultDay)=split('-',$dDefault);
  $nDay=request_int_range($sName.'_day',1,31,$nDefaultDay);
  $nMonth=request_int_range($sName.'_month',1,12,$nDefaultMonth);
  $nYear=request_int_range($sName.'_year',1900,2100,$nDefaultYear);
  $nTime=mktime(0,0,0,$nMonth,$nDay,$nYear);
  $dDate=date('Y-m-d',$nTime);
  return $dDate;
}
function request_domain($sName,$dDefault='',$sMethod='_REQUEST',$bDebug=FALSE) {
  global ${$sMethod};
  if (key_exists($sName,${$sMethod}) ) {
    return isdomain(${$sMethod}[$sName],$sDefault);
  }
  return $sDefault;
}

function isdomain($sName,$sDefault='') {
  if ( eregi('^([A-Z0-9-]{2,64}\.){1,3}[a-z]{2,4}$',$sName ) ) {
    return $sName;
  }
  return $sDefault;
  
}
function sort_table_head($aHeader,$sCurSort,$sCurDirect) {
  if ($sCurDirect=='asc' ) {
    $sNewDirect='desc';
  } else {
    $sNewDirect='asc';
  }
  $sHeader='<table class="datatable"><thead><tr>';  
  foreach ($aHeader as $key=>$value ) {
    if ( $sCurDirect==$key ) {
      $sHeader.="<th><a href=\"?order={$key}&dir={$sNewDirect}\"><u>{$value}</u></a></th>";
    } else {
      $sHeader.="<th><a href=\"?order={$key}&dir={$sCurDirect}\">{$value}</a></th>";
    } 
  }
  $sHeader.="</td></thead>";
  return $sHeader;
}

/**
 * retrieve a string from $_REQUEST super global and make sure it can be found
 * in an array.
 *
 * @param string $sName
 * @param array $aList
 * @param string $sDefault
 * @return string
 */
function request_in_list($sName,$aList,$sDefault='',$sMethod='_REQUEST',$bDebug=FALSE) {
  global ${$sMethod};
  if (key_exists($sName,${$sMethod}) ) {
    return in_list(${$sMethod}[$sName],$aList,$sDefault,$bDebug);
  }
  if ( $bDebug ) {
    dprint("request in list no value found for $sName in $sMethod");
  }
  return $sDefault;
}

/**
 * Validate that a value is in an array.
 *
 * @param string $sValue
 * @param array $aList
 * @param string $sDefault
 * @return string
 */

function in_list($sValue,$aList,$sDefault,$bDebug=FALSE) {
    if ( in_array($sValue,$aList) ) {

        return $sValue;
    }
    dprint("value $sValue not found in list returning default $sDefault");
    return $sDefault;
}

/**
 * Retrieve a date from the $_REQUEST super global array and
 * validate that it falls within a range.
 *
 * @param string $sName
 * @param date $dMin
 * @param date $dMax
 * @param string $dDefault
 * @return string
 */

function request_date_range($sName,$dMin,$dMax,$dDefault=FALSE,$sMethod='_REQUEST',$bDebug=FALSE) {
  global ${$sMethod};
  if ( $dDefault=='today') {
     $dDefault=date('Y-m-d');
  }
  if (key_exists("{$sName}_day",${$sMethod})) {
    return is_date_range(${$sMethod}[$sName],$dMin,$dMax,$dDefault);
  }
  if ( $bDebug ) {
    dprint("key {$sName}_day does not exist in method $sMethod");
  }
  return $dDefault;
}

function post_safe_text($sName,$dDefault=FALSE,$sSafeChars="[^A-Z0-9 ]") {
  if ( key_exists($sName,$_POST)) {
    $sValue=$_POST[$sName];
    $sValue=eregi_replace($sSafeChars,"",$sValue);
    return $sValue;
  }
  return $sDefault;
}

function request_safe_text($sName,$dDefault=FALSE,$sSafeChars="[^A-Z0-9 ]",$sMethod='_REQUEST',$bDebug=FALSE) {
  global ${$sMethod};
  if ( key_exists($sName,${$sMethod})) {
    $sValue=${$sMethod}[$sName];
    $sValue=eregi_replace($sSafeChars,"",$sValue);
    return $sValue;
  }
  return $sDefault;
}

/**
 * Check if a string is a date
 *
 * @param string $dValue
 * @param string $dDefault
 * @return string
 */

function is_date($dValue,$dDefault) {
    if ( ereg("[12][09][0-9][0-9]-[01][0-9]-[0-3][0-9]",$dValue)) {
        return $dValue;
    }
    return $dDefault;
}

/**
 * check if a value is a date within a given range.
 *
 * @param date $dValue
 * @param date $dMin
 * @param date $dMax
 * @param date $dDefault
 * @return date
 */
function is_date_range($dValue,$dMin,$dMax,$dDefault){
    $dValue=is_date($dValue,$dDefault);
    if ( $dValue<$dMin || $dValue>$dMax) {
        return $dDefault;
    }
    return $dValue;
}
/**
 * remove HTML special chars before printing a string.
 * good to avoid XSS
 *
 * @param string $sText
 */
function safe_print($sText){
    echo(htmlentities($sText));
}
/**
 * Dray a 'submit' button.
 *
 * @param string $sName
 * @param string $sValue
 * @return string
 */
function submit($sName='submit',$sValue='Submit') {
  $sValue=formsafe($sValue);
    return('<input class="formfield" type="submit" name="'.$sName.'" value="'.$sValue.'">');
}

function hidden($sName,$sValue) {
  $sValue=formsafe($sValue);
  return("<input type=\"hidden\" name=\"{$sName}\" value=\"{$sValue}\">");
}

function table_submit($sName='submit',$sValue='Submit') {
  return "<tr><td></td><td>".submit($sName,$sValue)."</td>";
}


/**
 * This function will read a tab delimited file into a keyed hash.
 *
 * @param string $sFileName
 * @param integer $nKey
 * @return array
 */
function read_file_to_keyedhash($sFileName,$nKey=0) {
    $aResult=array();
    $hFile=fopen($sFileName,'r');
    while($hFile && ! feof($hFile)) {
        $aLine=explode("\t",fgets($hFile));
        if (key_exists($nKey,$aLine)) {
            $aResult[$aLine[$nKey]]=$aLine;
        }
    }
    return $aResult;
}

